﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WindowsGame1.Extensions;
namespace WindowsGame1
{
    public class RectDungeon
    {
        int top, left, width, height;
        const int min_size = 5;
        RectDungeon leftChild;
        RectDungeon rightChild;
        public RectDungeon LeftChild { get { return leftChild; } }
        public RectDungeon RightChild { get { return rightChild; } }
        RectDungeon dungeon;
        readonly int _seed;
        private readonly Random _rnd;
        public RectDungeon(int seed,int top, int left, int height, int width)
        {
            this.top = top;
            this.left = left;
            this.height = height;
            this.width = width;
            _seed = seed;
            this._rnd = new Random(_seed);
        }
        public override string ToString()
        {
            byte dungeonCount = 0;
            var d = this.dungeon;
            if (d == null)
                return string.Empty;
            dungeonCount++;
            byte[][] lines = new byte[60][];
            for (int i = 0; i < 60; i++)
            {
                lines[i] = new byte[120];
                for (int j = 0; j < 120; j++)
                    lines[i][j] = 0;
            }
            for (int i = 0; i < d.height; i++)
            {
                lines[i] = new byte[120];
                for (int j = 0; j < d.width; j++)

                    lines[d.top + i][d.left + j] = dungeonCount;
            }
            var sb = new StringBuilder();
            for (int i = 0; i < 60; i++)
            {
                for (int j = 0; j < 120; j++)
                {
                    if (lines[i][j] == -1)
                        sb.Append('.');
                    else
                        sb.Append(lines[i][j]);
                }
                sb.AppendLine();
            }
            return sb.ToString();
           
        }
        public static void PrintDungeons(IEnumerable<RectDungeon> dungeons, Action<string> print, Action lineFinished)
        {
            byte[][] lines = new byte[60][];
            for (int i = 0; i < 60; i++)
            {
                lines[i] = new byte[120];
                for (int j = 0; j < 120; j++)
                    lines[i][j] = 0;
            }
            byte dungeonCount = 0;
            foreach (var r in dungeons)
            {
                if (r.dungeon == null)
                    continue;
                var d = r.dungeon;
                dungeonCount++;

                for (int i = 0; i < d.height; i++)
                {
                    for (int j = 0; j < d.width; j++)

                        lines[d.top + i][d.left + j] = dungeonCount;
                }
            }

            for (int i = 0; i < 60; i++)
            {
                for (int j = 0; j < 120; j++)
                {
                    if (lines[i][j] == 0)
                        print(".");
                    else
                       print(lines[i][j].ToString("X"));
                }
                lineFinished();
            }
        }
        public static void printDungeons(IEnumerable<RectDungeon> dungeons)
        {
            PrintDungeons(dungeons, Console.Write, Console.WriteLine);

        }

        public bool split()
        {
            if (leftChild != null)
                return false;
            bool horizontal = _rnd.NextBool();
            int max = (horizontal ? height : width) - min_size;
            if (max <= min_size)
                return false;
            int split = _rnd.NextI(max);
            if(split<min_size)
                split = min_size;
            if(horizontal)
            {
                leftChild = new RectDungeon(_seed, top, left, height - split, width);
                rightChild = new RectDungeon(_seed, top + split, left, height - split, width);
                return true;
            }
            leftChild = new RectDungeon(_seed, top, left, height, split);
            rightChild = new RectDungeon(_seed,top, left + split, height, width - split);
            return true;

        }
        public void generateDungeon()
        {
            if(leftChild!=null)
            {
                leftChild.generateDungeon();
                rightChild.generateDungeon();
            }
            else
            {
                int dungeonTop = (height - min_size <= 0) ? 0 : _rnd.NextI(height - min_size);
                int dungeonLeft = (width - min_size <= 0) ? 0 : _rnd.NextI(width - min_size);
                int dungeonHeight = Math.Max(_rnd.NextI(height - dungeonTop), min_size); ;
                int dungeonWidth = Math.Max(_rnd.NextI(width - dungeonLeft), min_size); ;
                dungeon = new RectDungeon(_seed,top + dungeonTop, left + dungeonLeft, dungeonHeight, dungeonWidth);
            }
        }
    }
}
